#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdbool.h>
#include <string.h>

#include "queue.h"
#include "util.h"

#define DEBUG 1
#define LOGD(fmt, ...) {if (DEBUG == 1 ) printf("[D][%s:%d] "fmt"\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);}

struct QUEUE *mQueue = NULL;
bool isBreak = false;

/**
 *  入列
 * */
void *threadEnqueue()
{
    LOGD("threadEnqueue");

    while (1)
    {
        if (mQueue == NULL)
        {
            break;
        }

        static int id   = 0;
        const char *str = get_string();

        struct USER_INFO *userInfo = (struct USER_INFO *)calloc(1, sizeof(struct USER_INFO));
        userInfo->id = id;
        userInfo->name = (char *)calloc(1, sizeof(char) * strlen(str));
        memcpy(userInfo->name, str, strlen(str));
        userInfo->sex  = rand() % 2;
        userInfo->age  = rand() % 30;

        LOGD("Enqueue ==> USER_INFO, id: %d, name: %s, sex: %d, age: %d",
             userInfo->id, userInfo->name, userInfo->sex, userInfo->age);

        mQueue->ENQUEUE(mQueue, userInfo);
        LOGD("COUNT_DEBUG: %ld", mQueue->QUEUE_COUNT_DEBUG(mQueue));
        LOGD("COUNT: %ld", mQueue->QUEUE_COUNT(mQueue));

        id++;
        uDelay(1000 * 1000);

        if (id == 10)  // 当id = 10时，释放队列，退出线程
        {
            mQueue->QUEUE_FREE(&mQueue, true);
            mQueue = NULL;
            isBreak = true;
        }
    }

    return NULL;
}

/**
 *  出列
 * */
void *threadDequeue()
{
    LOGD("threadDequeue");
    while (1)
    {
        if (mQueue == NULL)
        {
            break;
        }

        struct USER_INFO *userInfo = mQueue->DEQUEUE(mQueue);
        if (userInfo != NULL)
        {
            LOGD("Dequeue <== USER_INFO, id: %d, name: %s, sex: %d, age: %d",
                 userInfo->id, userInfo->name, userInfo->sex, userInfo->age);

            LOGD("COUNT_DEBUG: %ld", mQueue->QUEUE_COUNT_DEBUG(mQueue));
            LOGD("COUNT: %ld", mQueue->QUEUE_COUNT(mQueue));
        }
        else
        {
            LOGD("Queue is NULL!");
        }

        uDelay(3000 * 1000);
    }

    return NULL;
}

/**
 *  创建工作队列
 * */
void *createWorkThread()
{
    pthread_t ptEnqueue, ptDequeue;

    pthread_create(&ptEnqueue, NULL, threadEnqueue, NULL);
    pthread_detach(ptEnqueue);

    pthread_create(&ptDequeue, NULL, threadDequeue, NULL);
    pthread_detach(ptDequeue);

}

int main() {
    isBreak = false;

    srand((int)time(NULL));

    mQueue = queue_init(); // 初始化队列

    createWorkThread();

    while (1)
    {
        if (isBreak)
        {
            break;
        }
    }

    return 0;
}

